<?php if (!defined('BASEPATH')) exit('No direct access allowed.');

/**
 * 轨迹类
 * @author Calvin
 *
 */
class Traces
{

	const EVENT_UPLOAD_FILE=1;//上传文件
	const EVENT_DELETE_FILE=2;//删除文件
	const EVENT_DESTROY_FILE=3;//彻底删除文件
	const EVENT_RENAME_FILE=4;//文件重命名
	const EVENT_DOWNLOAD_SOURCE_FILE=5;//下载源文件
	const EVENT_DISABLE_SECURE_FILE=6;//'禁止访问受控副本',
	const EVENT_ENABLE_SECURE_FILE=7;//允许访问受控副本'
	const EVENT_DOWNLOAD_SECURE_FILE=8;//'下载受控副本',
	const EVENT_OPEN_SECURE_FILE=9;//'开始查阅受控副本',
	const EVENT_CLOSE_SECURE_FILE=10;//'关闭受控副本',
	const EVENT_DELETE_SECURE_FILE=11;//'销毁受控副本',
	const EVENT_SET_POLICY=12;//设置访问控制

	const EVENT_SET_LIFE_SPAN=13;//过期时间
	const EVENT_SET_OPEN_COUNTER=14;//只可查询一次
	const EVENT_SET_DELETE_AFTER_EXPIRED=15;//自动销毁
	const EVENT_SET_READ_PWD=16;//查阅密码

	const EVENT_SCREEN_SHOT_FILE = 17; //iOS截屏

	private static $relation=array(
		12=>array(13,14,15,16)
	);

	/**
	 * 获取策略的记录事件
	 * @param $desc 策略描述
	 * @return int|mixed
	 */
	public static function get_policy_event($desc)
	{
		$r = new ReflectionClass("Traces");
		$key = "EVENT_SET_".strtoupper($desc);
		$const = $r->getConstant($key);
		return $const===false?0:$const;
	}

	/**
	 * 获取事件的关联父级节点
	 * @param $event
	 * @return int|string
	 */
	public static function get_parent($event)
	{
		$find = 0;
		$event = (int)$event;
		foreach(self::$relation as $k=>$v)
		{
			if(in_array($event,$v))
			{
				$find = $k;
				break;
			}
		}
		return $find;
	}

	/**
	 * 获取事件的关联子节点
	 * @param $event
	 * @return null
	 */
	public static function get_child($event)
	{
		if(isset(self::$relation[$event]))
		{
			return self::$relation[$event];
		}
		else
		{
			return null;
		}
	}

	/**
	 * 跟踪文件
	 * @param $file_id 文件id
	 * @param $event 事件 如果$file_id为数组时，$event传的是父级事件
	 * @param string $start 开始的值
	 * @param string $end 修改后的值
	 * @param int $actor 操作人
	 * @param int $unsafe 是否为不安全记录
	 * @param int $hidden 是否隐藏
	 * @return bool
	 */
	public static function trace_file($file_id,$event,$start="",$end="",$actor=0,$unsafe=0,$hidden=0)
	{
		if(is_array($file_id) && count($file_id)<=0)
		{
			return false;
		}
		else if(empty($file_id) || !is_numeric($event) || !is_numeric($actor) || $actor<0)
		{
			return false;
		}
		$CI = & get_instance();
		$CI->load->model("file_trace_model");

		$ip = $CI->input->ip_address();
		$user_agent = $CI->input->server('HTTP_USER_AGENT');
		$CI->load->library("ip_attribution");
		$ip_attr = $CI->ip_attribution->find($ip);
		$city = trim($ip_attr[1]." ".$ip_attr[2]);
		$time = time();
		//添加父级事件记录
		$pid=0;
		//如果$file_id为数组时，$event传的是父级事件
		$parent_event = is_array($file_id)?$event:self::get_parent($event);
		if($parent_event===self::EVENT_SET_POLICY)
		{
			$parent_params = is_array($file_id)?$file_id[0]:array("file_id"=>$file_id,"event"=>$event,"start"=>$start,"end"=>$end,"actor"=>$actor);
			$parent_data=array(
				"file_id"=>$parent_params['file_id'],
				"event"=>self::EVENT_SET_POLICY,
				"start"=>"",
				"end"=>"",
				"relation"=>0,
				"actor"=>$parent_params['actor'],
				"unsafe"=>0,
				"hidden"=>0,
				"ts"=>$time,
				"actor_ip"=>$ip,
				"actor_city"=>$city,
				"user_agent"=>$user_agent
			);
			$add_parent = $CI->file_trace_model->add_trace($parent_data);
			if(!$add_parent)
			{
				return false;
			}
			$pid = $CI->file_trace_model->get_insert_id();
		}
		//批量添加
		if(is_array($file_id))
		{

			$data=array();
			foreach($file_id as $k=>$v)
			{
				if(!isset($v['file_id']) || !isset($v['event']))
				{
					continue;
				}
				$data[] = array(
					"file_id"=>$v['file_id'],
					"event"=>$v['event'],
					"start"=>isset($v['start'])?$v['start']:"",
					"end"=>isset($v['end'])?$v['end']:"",
					"relation"=>$pid,
					"actor"=>isset($v['actor'])?$v['actor']:0,
					"unsafe"=>isset($v['unsafe'])?$v['unsafe']:0,
					"hidden"=>isset($v['hidden'])?$v['hidden']:0,
					"ts"=>$time,
					"actor_ip"=>$ip,
					"actor_city"=>$city,
					"user_agent"=>$user_agent
				);
			}
			if(empty($data))
			{
				return false;
			}
			return $CI->file_trace_model->add_traces($data);
		}
		else
		{

			$data = array(
				"file_id"=>$file_id,
				"event"=>$event,
				"start"=>$start,
				"end"=>$end,
				"relation"=>$pid,
				"actor"=>$actor,
				"unsafe"=>$unsafe,
				"hidden"=>$hidden,
				"ts"=>$time,
				"actor_ip"=>$ip,
				"actor_city"=>$city,
				"user_agent"=>$user_agent
			);
			return $CI->file_trace_model->add_trace($data);
		}

	}

    /**
     * 下载文件的轨迹
     * @param $files_id 文件id 数组形式
     * @param $event
     * @return bool
     */
    public static function trace_download_batch($files_id, $event) {
        if (! is_array($files_id) || !is_numeric($event)) return FALSE;

        $CI = & get_instance();
        $CI->load->model("file_trace_model");

        $ip = $CI->input->ip_address();
		$user_agent = $CI->input->server('HTTP_USER_AGENT');
        $CI->load->library("ip_attribution");
        $ip_attr = $CI->ip_attribution->find($ip);
        $city = trim($ip_attr[1]." ".$ip_attr[2]);
        $time = time();

		$CI->load->service('login_service');
		$uid = 0;
		$find_uid = $CI->login_service->get_user_info('id');
		if (! empty($find_uid)) $uid = $find_uid;

        $data=array();
        foreach($files_id as $k=>$v) {
            $file_id = (! isset($v['file_id'])) ? (! isset($v['id'])) ? "" : $v['id'] : $v['file_id'];
            $data[] = array(
                "file_id"	=> $file_id,
				"actor" 	=> $uid,
                "event"		=> $event,
                "ts"		=> $time,
                "actor_ip"	=> $ip,
                "actor_city"=> $city,
				"user_agent"=> $user_agent
            );
        }
        if (empty($data)) return FALSE;

        if (count($data) == 1) return $CI->file_trace_model->add_trace($data[0]);

        return $CI->file_trace_model->add_traces($data);
    }
}
